import { Component, ChangeDetectionStrategy, OnInit, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
import { _HttpClient } from '@delon/theme';

/**
 * cron-generater
 * cron生成器
 * @author luoxm
 * @date 2019-10-12
 */
@Component({
  selector: 'cron',
  templateUrl: './cron.component.html',
  styleUrls: ['./cron.component.less'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CronComponent implements OnInit {
  decodes = [];
  spinning = false;
  @Output() readonly ok = new EventEmitter<any>();
  @Output() readonly cancel = new EventEmitter<any>();
  style = {
    display: 'block',
    height: '30px',
    lineHeight: '30px',
  };
  second = {
    cronEvery: '',
    incrementStart: '3',
    incrementIncrement: '5',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
  };
  minute = {
    cronEvery: '',
    incrementStart: '3',
    incrementIncrement: '5',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
  };
  hour = {
    cronEvery: '',
    incrementStart: '3',
    incrementIncrement: '5',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
  };
  day = {
    cronEvery: '',
    incrementStart: '1',
    incrementIncrement: '1',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
    cronLastSpecificDomDay: 1,
    cronDaysBeforeEomMinus: '',
    cronDaysNearestWeekday: '',
  };
  week = {
    cronEvery: '',
    incrementStart: '1',
    incrementIncrement: '1',
    specificSpecific: [],
    cronNthDayDay: 1,
    cronNthDayNth: '1',
  };
  month = {
    cronEvery: '',
    incrementStart: '3',
    incrementIncrement: '5',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
  };
  year = {
    cronEvery: '',
    incrementStart: '2019',
    incrementIncrement: '1',
    rangeStart: '',
    rangeEnd: '',
    specificSpecific: [],
  };
  output = {
    second: '',
    minute: '',
    hour: '',
    day: '',
    month: '',
    Week: '',
    year: '',
  };
  s60 = [];
  h24 = [];
  M12 = [];
  ys = [];
  ws = [];
  w7 = [];
  d31 = [];
  constructor(private http: _HttpClient, private cdr: ChangeDetectorRef) {}

  ngOnInit() {
    for (let i = 1; i <= 31; i++) {
      this.d31.push({ label: i, value: i });
    }
    for (let i = 0; i < 60; i++) {
      this.s60.push({ label: i, value: i });
    }
    for (let i = 0; i < 24; i++) {
      this.h24.push({ label: i, value: i });
    }
    for (let i = 1; i <= 12; i++) {
      this.M12.push({ label: i, value: i });
    }
    for (let i = 1; i <= 100; i++) {
      this.ys.push({ label: 2018 + i, value: 2018 + i });
    }

    this.ws.push({ label: '星期天', value: 1 });
    this.ws.push({ label: '星期一', value: 2 });
    this.ws.push({ label: '星期二', value: 3 });
    this.ws.push({ label: '星期三', value: 4 });
    this.ws.push({ label: '星期四', value: 5 });
    this.ws.push({ label: '星期五', value: 6 });
    this.ws.push({ label: '星期六', value: 7 });

    this.w7.push({ label: '星期天', value: 'SUN' });
    this.w7.push({ label: '星期一', value: 'MON' });
    this.w7.push({ label: '星期二', value: 'TUE' });
    this.w7.push({ label: '星期三', value: 'WED' });
    this.w7.push({ label: '星期四', value: 'THU' });
    this.w7.push({ label: '星期五', value: 'FRI' });
    this.w7.push({ label: '星期六', value: 'SAT' });
  }

  secondsText() {
    let seconds = '';
    const cronEvery = this.second.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        seconds = '*';
        break;
      case '2':
        seconds = this.second.incrementStart + '/' + this.second.incrementIncrement;
        break;
      case '3':
        this.second.specificSpecific.map(val => {
          seconds += val + ',';
        });
        seconds = seconds.slice(0, -1);
        break;
      case '4':
        seconds = this.second.rangeStart + '-' + this.second.rangeEnd;
        break;
    }
    return seconds;
  }

  minutesText() {
    let minutes = '';
    const cronEvery = this.minute.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        minutes = '*';
        break;
      case '2':
        minutes = this.minute.incrementStart + '/' + this.minute.incrementIncrement;
        break;
      case '3':
        this.minute.specificSpecific.map(val => {
          minutes += val + ',';
        });
        minutes = minutes.slice(0, -1);
        break;
      case '4':
        minutes = this.minute.rangeStart + '-' + this.minute.rangeEnd;
        break;
    }
    return minutes;
  }
  hoursText() {
    let hours = '';
    const cronEvery = this.hour.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        hours = '*';
        break;
      case '2':
        hours = this.hour.incrementStart + '/' + this.hour.incrementIncrement;
        break;
      case '3':
        this.hour.specificSpecific.map(val => {
          hours += val + ',';
        });
        hours = hours.slice(0, -1);
        break;
      case '4':
        hours = this.hour.rangeStart + '-' + this.hour.rangeEnd;
        break;
    }
    return hours;
  }

  daysText() {
    let days = '';
    const cronEvery = this.day.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        break;
      case '2':
      case '4':
      case '11':
        days = '?';
        break;
      case '3':
        days = this.day.incrementStart + '/' + this.day.incrementIncrement;
        break;
      case '5':
        this.day.specificSpecific.map(val => {
          days += val + ',';
        });
        days = days.slice(0, -1);
        break;
      case '6':
        days = 'L';
        break;
      case '7':
        days = 'LW';
        break;
      case '8':
        days = this.day.cronLastSpecificDomDay + 'L';
        break;
      case '9':
        days = 'L-' + this.day.cronDaysBeforeEomMinus;
        break;
      case '10':
        days = this.day.cronDaysNearestWeekday + 'W';
        break;
    }
    return days;
  }

  weeksText() {
    let weeks = '';
    const cronEvery = this.day.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
      case '3':
      case '5':
        weeks = '?';
        break;
      case '2':
        weeks = this.week.incrementStart + '/' + this.week.incrementIncrement;
        break;
      case '4':
        this.week.specificSpecific.map(val => {
          weeks += val + ',';
        });
        weeks = weeks.slice(0, -1);
        break;
      case '6':
      case '7':
      case '8':
      case '9':
      case '10':
        weeks = '?';
        break;
      case '11':
        weeks = this.week.cronNthDayDay + '#' + this.week.cronNthDayNth;
        break;
    }
    return weeks;
  }
  monthsText() {
    let months = '';
    const cronEvery = this.month.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        months = '*';
        break;
      case '2':
        months = this.month.incrementStart + '/' + this.month.incrementIncrement;
        break;
      case '3':
        this.month.specificSpecific.map(val => {
          months += val + ',';
        });
        months = months.slice(0, -1);
        break;
      case '4':
        months = this.month.rangeStart + '-' + this.month.rangeEnd;
        break;
    }
    return months;
  }
  yearsText() {
    let years = '';
    const cronEvery = this.year.cronEvery;
    switch (cronEvery.toString()) {
      case '1':
        years = '*';
        break;
      case '2':
        years = this.year.incrementStart + '/' + this.year.incrementIncrement;
        break;
      case '3':
        this.year.specificSpecific.map(val => {
          years += val + ',';
        });
        years = years.slice(0, -1);
        break;
      case '4':
        years = this.year.rangeStart + '-' + this.year.rangeEnd;
        break;
    }
    return years;
  }
  cron() {
    return `${this.secondsText() || '*'} ${this.minutesText() || '*'} ${this.hoursText() || '*'} ${this.daysText() ||
      '*'} ${this.monthsText() || '*'} ${this.weeksText() || '?'} ${this.yearsText() || '*'}`;
  }

  save() {
    this.ok.emit(this.cron());
  }
  close() {
    this.cancel.emit();
  }

  api() {
    this.spinning = true;
    this.http.get<{ data: any }>(`/cf/job/sys-job/lastnexttime?cornExpression=${this.cron()}&top=5`).subscribe(res => {
      this.spinning = false;
      this.decodes = res.data;
      this.cdr.markForCheck();
    });
  }
}
